Global settings

Clear work space and set global variables

# Clear memory
rm(list=ls()) # Clear environmental variables
gc() # memory garbage removal
          used  (Mb) gc trigger  (Mb) limit (Mb) max used  (Mb)
Ncells 4229933 226.0    7801202 416.7         NA  7801202 416.7
Vcells 7837455  59.8   14786712 112.9      16384 12255511  93.6
# set global options
knitr::opts_chunk$set(fig.width=12, fig.height=8, warning=FALSE, message=FALSE)

Load libaries

if(!require("pacman", quietly=T)) install.packages("pacman")
pacman::p_load(osfr,tinytex,tidyverse,keyring,knitr,readxl,data.table,colorspace, lpSolve,irr,here,lme4,broom,psych,zoo,units,ggdist,cowplot,ggcorrplot,dplyr, patchwork, cowplot, ggpmisc, forcats, pwr, ggpmisc, simstudy, explore, car,VIM,mice,flextable,here, remotes,magrittr,reshape2,descr,table1,tableone,gmodels,xtable,lavaan,corrplot,caret,corrgram,Hmisc,polycor,lavaan,kableExtra,DiagrammeR,grid,Gmisc,epitools)

Set up local tempfolder for raw and processed data files

# Get the path to the session's temporary directory
session_temp_dir <- tempdir()

# Define paths for the specific temporary subdirectories
raw_data_dir <- file.path(session_temp_dir, "raw_data")
processed_data_dir <- file.path(session_temp_dir, "processed_data")

# Create the 'raw_data' subdirectory if it doesn't exist
if (!dir.exists(raw_data_dir)) {
  dir.create(raw_data_dir)
}

# Create the 'processed_data' subdirectory if it doesn't exist
if (!dir.exists(processed_data_dir)) {
  dir.create(processed_data_dir)
}

 

Authenticate R to OSF connection

osf_auth(keyring :: key_get("osf"))
Registered PAT from the provided token

OSF nodes


# Define OSF node IDs at the beginning
# raw_data_node_id <- "yxsqb"   # Master Thesis Raw Data Node or other Raw Data Node
# raw_data_node_id <- "gpj2v"  # https://osf.io/gpj2v/ Quantify Occupational Injury
 raw_data_node_id <- "dpgby"  # https://osf.io/dpgby/ Art Business Education
# raw_data_node_id <- "z6jfn" # https://osf.io/z6jfn/ Housing prices
# raw_data_node_id <- "gu7ny" # https://osf.io/gu7ny/ Hmm53a-2425-GR1
# raw_data_node_id <- "prw4a" # https://osf.io/prw4a/ Hmm53a-2425-GR2
# raw_data_node_id <- "gxw3v" # https://osf.io/gxw3v/ Hmm53a-2425-GR3

# processed_data_node_id <- "e4rdh"  # Master Thesis Processed Data Node 
# processed_data_node_id <- "q4wgm"  # https://osf.io/q4wgm/ Quantify Occupational Injury
 processed_data_node_id <- "akgf2"  # https://osf.io/akgf2/ Art Business Education
# processed_data_node_id <- "6heqg"  # https://osf.io/6heqg/ Housing prices
# processed_data_node_id <- "76tn5"  # https://osf.io/76tn5/ Hmm53a-2425-GR1
# processed_data_node_id <- "ab6hg"  # https://osf.io/ab6hg/ Hmm53a-2425-GR2
# processed_data_node_id <- "tyhbk"  # https://osf.io/tyhbk/ Hmm53a-2425-GR3 

Download Zotero_SynthesisTable.csv


osf_retrieve_node(processed_data_node_id) %>%
  osf_ls_files(pattern = "Zotero_SynthesisTable.csv") %>%
   osf_download(path = raw_data_dir, conflicts="overwrite",progress=TRUE)

Load Zotero tag export file into R data frame


csv_file <- list.files(path = raw_data_dir, pattern = "\\.csv$", full.names = TRUE)

if (length(csv_file) == 0) {
  stop("Error: No csv file found in the specified directory.")
}



# standard pathname
csv_file[1] <- file.path(dirname(csv_file[1]), basename(csv_file[1]))
if (!file.exists(csv_file[1])) {
  stop("File does not exist. Check the path.")
}

print(csv_file)
[1] "/var/folders/v0/q9_by2r90yqg0g8s8rykvby40000gn/T//RtmpMEfHG2/raw_data/Zotero_SynthesisTable.csv"

Select first CSV file

# Read the Markdown file
Zotero_SynthesisTable <- read.csv(csv_file[1], encoding = "UTF-8")

# Check if the file is empty
if (length(Zotero_SynthesisTable) == 0) {
  stop("Error: The csv file is empty.")
}

manupulations

# Rename the dataframe
datacleaningtable <- Zotero_SynthesisTable
# Load necessary package
library(dplyr)

# Remove the column 'included_bibliometrics' if it exists
datacleaningtable <- datacleaningtable %>% select(-included_metaanalysis, -concept)

# Print the updated dataframe
print(datacleaningtable)
# Load necessary library
library(dplyr)

# Define column groups for merging
columns_methods <- c("method_arts", "method_theoretical", "method_qualitative", 
                     "method_quantitative", "method_mixed", "method_pre_post", 
                     "method_baseline_group", "method_literaturereview")

columns_limitations <- c("limitation_other", "limitation_descriptive", 
                         "limitation_research", "limitation_poor_research")

columns_disciplines <- c("discipline_leadership", "discipline_entrepreneurship", 
                         "discipline_management", "discipline_arts", 
                         "discipline_interdisciplinairy", "discipline_marketing", "discipline_sustainability")

columns_objectives <- c("aim", "research_question", "hypothesis")

columns_location <- c("location_europe", "location_america", "location_asia", "location_southamerica")

columns_results <- c("result_teaching", "result_proces", "result_motivation", 
                     "result_outcome", "result_perspective", 
                     "result_organisational_outcome")

columns_collected <- c("seed_paper", "second_batch", "included_biblimetrics", 
                       "first_batch", "included_business")

columns_source <- c("source_measure", "source_business", "source_artbasedmethod", 
                    "source_vangogh", "source_creativity", "source_slr")

columns_educationtype <- c("k12_education", "social_sustainability_education", "higher_education")

# Function to merge selected columns into one while keeping column names
merge_columns <- function(df, new_column, old_columns) {
  df %>%
    mutate(!!new_column := apply(.[old_columns], 1, function(x) {
      paste(names(x)[!is.na(x) & x != ""], x[!is.na(x) & x != ""], sep = ": ", collapse = "; ")
    })) %>%
    select(-all_of(old_columns))  # Remove old columns
}

# Apply merging function to each group
datacleaningtable <- datacleaningtable %>%
  merge_columns("methods", columns_methods) %>%
  merge_columns("limitations", columns_limitations) %>%
  merge_columns("disciplines", columns_disciplines) %>%
  merge_columns("objectives", columns_objectives) %>%
  merge_columns("location", columns_location) %>%
  merge_columns("results", columns_results) %>%
  merge_columns("collected", columns_collected) %>%
  merge_columns("source", columns_source) %>%
  merge_columns("educationtype", columns_educationtype)

# Display only the 'year' column along with all newly created columns
print(datacleaningtable %>% select(methods, limitations, disciplines, objectives, 
                                   location, results, collected, source, educationtype), width = Inf)
NA
# Load necessary library
library(dplyr)

# Function to merge selected columns into an existing column while keeping column names
merge_into_existing_column <- function(df, existing_column, new_columns) {
  existing_cols <- intersect(new_columns, colnames(df))  # Keep only existing columns

  if (length(existing_cols) > 0) {  # Only proceed if columns exist
    df <- df %>%
      mutate(!!existing_column := apply(.[c(existing_column, existing_cols)], 1, function(x) {
        paste(names(x)[!is.na(x) & x != ""], x[!is.na(x) & x != ""], sep = ": ", collapse = "; ")
      })) %>%
      select(-all_of(existing_cols))  # Remove merged columns
  }
  
  return(df)
}

# Apply merging function to move columns under existing ones
datacleaningtable <- datacleaningtable %>%
  merge_into_existing_column("error", c("question")) %>%
  merge_into_existing_column("artform", c("art_making", "illustration_of_essence", "skill_transfer")) %>%
  merge_into_existing_column("theory", c("educational_theory", "scientific_explanation", "educational_the"))

# Display updated dataset
print(datacleaningtable %>% select(error, artform, theory), width = Inf)

# Define the desired column order (assuming the dataframe already has 'author' as desired)
desired_order <- c("title", "author", "collected", "NoTag", "source", 
                   "objectives", "methods", "data_collection", "number", "participants", 
                   "data_analysis", "case", "disciplines", "location", "educationtype", 
                   "business_context", "artform", "reason_art", "learning_outcome", 
                   "outcome_organisation", "theory", "interesting_perspective", 
                   "consideration_research", "consideration_teaching", "consideration_business", 
                   "recommendation_teaching", "recommendation_business", 
                   "recommendation_research", "limitations", "future_research")

# Reorder columns with the unmentioned ones appended at the end.
datacleaningtable20250326 <- datacleaningtable %>%
  select(all_of(intersect(desired_order, colnames(.))),
         everything())

# Remove duplicate columns in case any appear twice.
datacleaningtable20250326 <- datacleaningtable20250326[, !duplicated(names(datacleaningtable20250326))]

# Display the updated dataframe
print(datacleaningtable20250326, width = Inf)
NA
# Load the necessary package
library(openxlsx)
Warning: package ‘openxlsx’ was built under R version 4.3.3
# Define the file path
file_path <- "/Users/Accounttijdelijk/Desktop/datacleaningtable20250326.xlsx"

# Create a new workbook and add a worksheet
wb <- createWorkbook()
addWorksheet(wb, "Sheet1")

# Write the data to the worksheet
writeData(wb, sheet = "Sheet1", datacleaningtable20250326)

# Define style for NA or empty cells
na_style <- createStyle(fgFill = "#FFD1D1")  # light red background

# Loop through each cell and apply style if it's NA or empty string
for (i in 1:nrow(datacleaningtable20250326)) {
  for (j in 1:ncol(datacleaningtable20250326)) {
    value <- datacleaningtable20250326[i, j]
    if (is.na(value) || trimws(as.character(value)) == "") {
      addStyle(wb, sheet = "Sheet1", style = na_style, rows = i + 1, cols = j, gridExpand = TRUE)
    }
  }
}

# Save the workbook
saveWorkbook(wb, file = file_path, overwrite = TRUE)

# Confirm the file was saved
cat("File saved to:", file_path)
File saved to: /Users/Accounttijdelijk/Desktop/datacleaningtable20250326.xlsx
LS0tCnRpdGxlOiAiU3RlcCAzIC0gUiBkYXRhIGNsZWFuaW5nIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6CiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgKLS0tCgojIEdsb2JhbCBzZXR0aW5ncwoKIyMgQ2xlYXIgd29yayBzcGFjZSBhbmQgc2V0IGdsb2JhbCB2YXJpYWJsZXMKYGBge3IgZ2xvYmFsLW9wdGlvbnN9CiMgQ2xlYXIgbWVtb3J5CnJtKGxpc3Q9bHMoKSkgIyBDbGVhciBlbnZpcm9ubWVudGFsIHZhcmlhYmxlcwpnYygpICMgbWVtb3J5IGdhcmJhZ2UgcmVtb3ZhbAojIHNldCBnbG9iYWwgb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTgsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UpCgpgYGAKCiMjIExvYWQgbGliYXJpZXMgCmBgYHtyIGxvYWQtcGFja2FnZXN9CmlmKCFyZXF1aXJlKCJwYWNtYW4iLCBxdWlldGx5PVQpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQpwYWNtYW46OnBfbG9hZChvc2ZyLHRpbnl0ZXgsdGlkeXZlcnNlLGtleXJpbmcsa25pdHIscmVhZHhsLGRhdGEudGFibGUsY29sb3JzcGFjZSwgbHBTb2x2ZSxpcnIsaGVyZSxsbWU0LGJyb29tLHBzeWNoLHpvbyx1bml0cyxnZ2Rpc3QsY293cGxvdCxnZ2NvcnJwbG90LGRwbHlyLCBwYXRjaHdvcmssIGNvd3Bsb3QsIGdncG1pc2MsIGZvcmNhdHMsIHB3ciwgZ2dwbWlzYywgc2ltc3R1ZHksIGV4cGxvcmUsIGNhcixWSU0sbWljZSxmbGV4dGFibGUsaGVyZSwgcmVtb3RlcyxtYWdyaXR0cixyZXNoYXBlMixkZXNjcix0YWJsZTEsdGFibGVvbmUsZ21vZGVscyx4dGFibGUsbGF2YWFuLGNvcnJwbG90LGNhcmV0LGNvcnJncmFtLEhtaXNjLHBvbHljb3IsbGF2YWFuLGthYmxlRXh0cmEsRGlhZ3JhbW1lUixncmlkLEdtaXNjLGVwaXRvb2xzKQpgYGAKCgojIyBTZXQgdXAgbG9jYWwgdGVtcGZvbGRlciBmb3IgcmF3IGFuZCBwcm9jZXNzZWQgZGF0YSBmaWxlcwpgYGB7ciBsb2NhbC10ZW1wZm9sZGVyfQojIEdldCB0aGUgcGF0aCB0byB0aGUgc2Vzc2lvbidzIHRlbXBvcmFyeSBkaXJlY3RvcnkKc2Vzc2lvbl90ZW1wX2RpciA8LSB0ZW1wZGlyKCkKCiMgRGVmaW5lIHBhdGhzIGZvciB0aGUgc3BlY2lmaWMgdGVtcG9yYXJ5IHN1YmRpcmVjdG9yaWVzCnJhd19kYXRhX2RpciA8LSBmaWxlLnBhdGgoc2Vzc2lvbl90ZW1wX2RpciwgInJhd19kYXRhIikKcHJvY2Vzc2VkX2RhdGFfZGlyIDwtIGZpbGUucGF0aChzZXNzaW9uX3RlbXBfZGlyLCAicHJvY2Vzc2VkX2RhdGEiKQoKIyBDcmVhdGUgdGhlICdyYXdfZGF0YScgc3ViZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QKaWYgKCFkaXIuZXhpc3RzKHJhd19kYXRhX2RpcikpIHsKICBkaXIuY3JlYXRlKHJhd19kYXRhX2RpcikKfQoKIyBDcmVhdGUgdGhlICdwcm9jZXNzZWRfZGF0YScgc3ViZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QKaWYgKCFkaXIuZXhpc3RzKHByb2Nlc3NlZF9kYXRhX2RpcikpIHsKICBkaXIuY3JlYXRlKHByb2Nlc3NlZF9kYXRhX2RpcikKfQoKIApgYGAKCgojIyBBdXRoZW50aWNhdGUgUiB0byBPU0YgY29ubmVjdGlvbgpgYGB7ciBvc2YtYXV0aGVudGljYXRpb259Cm9zZl9hdXRoKGtleXJpbmcgOjoga2V5X2dldCgib3NmIikpCmBgYAojIyBPU0Ygbm9kZXMKYGBge3IgT1NGLW5vZGVzfQoKIyBEZWZpbmUgT1NGIG5vZGUgSURzIGF0IHRoZSBiZWdpbm5pbmcKIyByYXdfZGF0YV9ub2RlX2lkIDwtICJ5eHNxYiIgICAjIE1hc3RlciBUaGVzaXMgUmF3IERhdGEgTm9kZSBvciBvdGhlciBSYXcgRGF0YSBOb2RlCiMgcmF3X2RhdGFfbm9kZV9pZCA8LSAiZ3BqMnYiICAjIGh0dHBzOi8vb3NmLmlvL2dwajJ2LyBRdWFudGlmeSBPY2N1cGF0aW9uYWwgSW5qdXJ5CiByYXdfZGF0YV9ub2RlX2lkIDwtICJkcGdieSIgICMgaHR0cHM6Ly9vc2YuaW8vZHBnYnkvIEFydCBCdXNpbmVzcyBFZHVjYXRpb24KIyByYXdfZGF0YV9ub2RlX2lkIDwtICJ6NmpmbiIgIyBodHRwczovL29zZi5pby96Nmpmbi8gSG91c2luZyBwcmljZXMKIyByYXdfZGF0YV9ub2RlX2lkIDwtICJndTdueSIgIyBodHRwczovL29zZi5pby9ndTdueS8gSG1tNTNhLTI0MjUtR1IxCiMgcmF3X2RhdGFfbm9kZV9pZCA8LSAicHJ3NGEiICMgaHR0cHM6Ly9vc2YuaW8vcHJ3NGEvIEhtbTUzYS0yNDI1LUdSMgojIHJhd19kYXRhX25vZGVfaWQgPC0gImd4dzN2IiAjIGh0dHBzOi8vb3NmLmlvL2d4dzN2LyBIbW01M2EtMjQyNS1HUjMKCiMgcHJvY2Vzc2VkX2RhdGFfbm9kZV9pZCA8LSAiZTRyZGgiICAjIE1hc3RlciBUaGVzaXMgUHJvY2Vzc2VkIERhdGEgTm9kZSAKIyBwcm9jZXNzZWRfZGF0YV9ub2RlX2lkIDwtICJxNHdnbSIgICMgaHR0cHM6Ly9vc2YuaW8vcTR3Z20vIFF1YW50aWZ5IE9jY3VwYXRpb25hbCBJbmp1cnkKIHByb2Nlc3NlZF9kYXRhX25vZGVfaWQgPC0gImFrZ2YyIiAgIyBodHRwczovL29zZi5pby9ha2dmMi8gQXJ0IEJ1c2luZXNzIEVkdWNhdGlvbgojIHByb2Nlc3NlZF9kYXRhX25vZGVfaWQgPC0gIjZoZXFnIiAgIyBodHRwczovL29zZi5pby82aGVxZy8gSG91c2luZyBwcmljZXMKIyBwcm9jZXNzZWRfZGF0YV9ub2RlX2lkIDwtICI3NnRuNSIgICMgaHR0cHM6Ly9vc2YuaW8vNzZ0bjUvIEhtbTUzYS0yNDI1LUdSMQojIHByb2Nlc3NlZF9kYXRhX25vZGVfaWQgPC0gImFiNmhnIiAgIyBodHRwczovL29zZi5pby9hYjZoZy8gSG1tNTNhLTI0MjUtR1IyCiMgcHJvY2Vzc2VkX2RhdGFfbm9kZV9pZCA8LSAidHloYmsiICAjIGh0dHBzOi8vb3NmLmlvL3R5aGJrLyBIbW01M2EtMjQyNS1HUjMgCmBgYAoKIyBEb3dubG9hZCBab3Rlcm9fU3ludGhlc2lzVGFibGUuY3N2IApgYGB7ciBnZXQtcHJvY2Vzc2VkLWRhdGEtb3NmLCBlY2hvPVRSVUUsIGluY2x1ZGU9VFJVRSwgcmVzdWx0cz0naGlkZSd9Cgpvc2ZfcmV0cmlldmVfbm9kZShwcm9jZXNzZWRfZGF0YV9ub2RlX2lkKSAlPiUKICBvc2ZfbHNfZmlsZXMocGF0dGVybiA9ICJab3Rlcm9fU3ludGhlc2lzVGFibGUuY3N2IikgJT4lCiAgIG9zZl9kb3dubG9hZChwYXRoID0gcmF3X2RhdGFfZGlyLCBjb25mbGljdHM9Im92ZXJ3cml0ZSIscHJvZ3Jlc3M9VFJVRSkKCmBgYAoKIyMgTG9hZCBab3Rlcm8gdGFnIGV4cG9ydCBmaWxlIGludG8gUiBkYXRhIGZyYW1lCmBgYHtyIGxpc3QtY3N2LWZpbGVzfQoKY3N2X2ZpbGUgPC0gbGlzdC5maWxlcyhwYXRoID0gcmF3X2RhdGFfZGlyLCBwYXR0ZXJuID0gIlxcLmNzdiQiLCBmdWxsLm5hbWVzID0gVFJVRSkKCmlmIChsZW5ndGgoY3N2X2ZpbGUpID09IDApIHsKICBzdG9wKCJFcnJvcjogTm8gY3N2IGZpbGUgZm91bmQgaW4gdGhlIHNwZWNpZmllZCBkaXJlY3RvcnkuIikKfQoKCgojIHN0YW5kYXJkIHBhdGhuYW1lCmNzdl9maWxlWzFdIDwtIGZpbGUucGF0aChkaXJuYW1lKGNzdl9maWxlWzFdKSwgYmFzZW5hbWUoY3N2X2ZpbGVbMV0pKQppZiAoIWZpbGUuZXhpc3RzKGNzdl9maWxlWzFdKSkgewogIHN0b3AoIkZpbGUgZG9lcyBub3QgZXhpc3QuIENoZWNrIHRoZSBwYXRoLiIpCn0KCnByaW50KGNzdl9maWxlKQpgYGAKCiMgU2VsZWN0IGZpcnN0IENTViBmaWxlCgpgYGB7ciBsb2FkLWNzdi1maWxlfQojIFJlYWQgdGhlIE1hcmtkb3duIGZpbGUKWm90ZXJvX1N5bnRoZXNpc1RhYmxlIDwtIHJlYWQuY3N2KGNzdl9maWxlWzFdLCBlbmNvZGluZyA9ICJVVEYtOCIpCgojIENoZWNrIGlmIHRoZSBmaWxlIGlzIGVtcHR5CmlmIChsZW5ndGgoWm90ZXJvX1N5bnRoZXNpc1RhYmxlKSA9PSAwKSB7CiAgc3RvcCgiRXJyb3I6IFRoZSBjc3YgZmlsZSBpcyBlbXB0eS4iKQp9CgpgYGAKCiMjIyMjIyMjIyMgbWFudXB1bGF0aW9ucyAKCmBgYHtyIHJlbmFtZSBkYXRhc2V0fQojIFJlbmFtZSB0aGUgZGF0YWZyYW1lCmRhdGFjbGVhbmluZ3RhYmxlIDwtIFpvdGVyb19TeW50aGVzaXNUYWJsZQpgYGAKCmBgYHtyIHJlbW92ZSBjb2x1bW5zfQojIExvYWQgbmVjZXNzYXJ5IHBhY2thZ2UKbGlicmFyeShkcGx5cikKCiMgUmVtb3ZlIHRoZSBjb2x1bW4gJ2luY2x1ZGVkX2JpYmxpb21ldHJpY3MnIGlmIGl0IGV4aXN0cwpkYXRhY2xlYW5pbmd0YWJsZSA8LSBkYXRhY2xlYW5pbmd0YWJsZSAlPiUgc2VsZWN0KC1pbmNsdWRlZF9tZXRhYW5hbHlzaXMsIC1jb25jZXB0KQoKIyBQcmludCB0aGUgdXBkYXRlZCBkYXRhZnJhbWUKcHJpbnQoZGF0YWNsZWFuaW5ndGFibGUpCmBgYAoKYGBge3IgbWVyZ2UgdG8gbmV3fQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcnkKbGlicmFyeShkcGx5cikKCiMgRGVmaW5lIGNvbHVtbiBncm91cHMgZm9yIG1lcmdpbmcKY29sdW1uc19tZXRob2RzIDwtIGMoIm1ldGhvZF9hcnRzIiwgIm1ldGhvZF90aGVvcmV0aWNhbCIsICJtZXRob2RfcXVhbGl0YXRpdmUiLCAKICAgICAgICAgICAgICAgICAgICAgIm1ldGhvZF9xdWFudGl0YXRpdmUiLCAibWV0aG9kX21peGVkIiwgIm1ldGhvZF9wcmVfcG9zdCIsIAogICAgICAgICAgICAgICAgICAgICAibWV0aG9kX2Jhc2VsaW5lX2dyb3VwIiwgIm1ldGhvZF9saXRlcmF0dXJlcmV2aWV3IikKCmNvbHVtbnNfbGltaXRhdGlvbnMgPC0gYygibGltaXRhdGlvbl9vdGhlciIsICJsaW1pdGF0aW9uX2Rlc2NyaXB0aXZlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAibGltaXRhdGlvbl9yZXNlYXJjaCIsICJsaW1pdGF0aW9uX3Bvb3JfcmVzZWFyY2giKQoKY29sdW1uc19kaXNjaXBsaW5lcyA8LSBjKCJkaXNjaXBsaW5lX2xlYWRlcnNoaXAiLCAiZGlzY2lwbGluZV9lbnRyZXByZW5ldXJzaGlwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAiZGlzY2lwbGluZV9tYW5hZ2VtZW50IiwgImRpc2NpcGxpbmVfYXJ0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgImRpc2NpcGxpbmVfaW50ZXJkaXNjaXBsaW5haXJ5IiwgImRpc2NpcGxpbmVfbWFya2V0aW5nIiwgImRpc2NpcGxpbmVfc3VzdGFpbmFiaWxpdHkiKQoKY29sdW1uc19vYmplY3RpdmVzIDwtIGMoImFpbSIsICJyZXNlYXJjaF9xdWVzdGlvbiIsICJoeXBvdGhlc2lzIikKCmNvbHVtbnNfbG9jYXRpb24gPC0gYygibG9jYXRpb25fZXVyb3BlIiwgImxvY2F0aW9uX2FtZXJpY2EiLCAibG9jYXRpb25fYXNpYSIsICJsb2NhdGlvbl9zb3V0aGFtZXJpY2EiKQoKY29sdW1uc19yZXN1bHRzIDwtIGMoInJlc3VsdF90ZWFjaGluZyIsICJyZXN1bHRfcHJvY2VzIiwgInJlc3VsdF9tb3RpdmF0aW9uIiwgCiAgICAgICAgICAgICAgICAgICAgICJyZXN1bHRfb3V0Y29tZSIsICJyZXN1bHRfcGVyc3BlY3RpdmUiLCAKICAgICAgICAgICAgICAgICAgICAgInJlc3VsdF9vcmdhbmlzYXRpb25hbF9vdXRjb21lIikKCmNvbHVtbnNfY29sbGVjdGVkIDwtIGMoInNlZWRfcGFwZXIiLCAic2Vjb25kX2JhdGNoIiwgImluY2x1ZGVkX2JpYmxpbWV0cmljcyIsIAogICAgICAgICAgICAgICAgICAgICAgICJmaXJzdF9iYXRjaCIsICJpbmNsdWRlZF9idXNpbmVzcyIpCgpjb2x1bW5zX3NvdXJjZSA8LSBjKCJzb3VyY2VfbWVhc3VyZSIsICJzb3VyY2VfYnVzaW5lc3MiLCAic291cmNlX2FydGJhc2VkbWV0aG9kIiwgCiAgICAgICAgICAgICAgICAgICAgInNvdXJjZV92YW5nb2doIiwgInNvdXJjZV9jcmVhdGl2aXR5IiwgInNvdXJjZV9zbHIiKQoKY29sdW1uc19lZHVjYXRpb250eXBlIDwtIGMoImsxMl9lZHVjYXRpb24iLCAic29jaWFsX3N1c3RhaW5hYmlsaXR5X2VkdWNhdGlvbiIsICJoaWdoZXJfZWR1Y2F0aW9uIikKCiMgRnVuY3Rpb24gdG8gbWVyZ2Ugc2VsZWN0ZWQgY29sdW1ucyBpbnRvIG9uZSB3aGlsZSBrZWVwaW5nIGNvbHVtbiBuYW1lcwptZXJnZV9jb2x1bW5zIDwtIGZ1bmN0aW9uKGRmLCBuZXdfY29sdW1uLCBvbGRfY29sdW1ucykgewogIGRmICU+JQogICAgbXV0YXRlKCEhbmV3X2NvbHVtbiA6PSBhcHBseSguW29sZF9jb2x1bW5zXSwgMSwgZnVuY3Rpb24oeCkgewogICAgICBwYXN0ZShuYW1lcyh4KVshaXMubmEoeCkgJiB4ICE9ICIiXSwgeFshaXMubmEoeCkgJiB4ICE9ICIiXSwgc2VwID0gIjogIiwgY29sbGFwc2UgPSAiOyAiKQogICAgfSkpICU+JQogICAgc2VsZWN0KC1hbGxfb2Yob2xkX2NvbHVtbnMpKSAgIyBSZW1vdmUgb2xkIGNvbHVtbnMKfQoKIyBBcHBseSBtZXJnaW5nIGZ1bmN0aW9uIHRvIGVhY2ggZ3JvdXAKZGF0YWNsZWFuaW5ndGFibGUgPC0gZGF0YWNsZWFuaW5ndGFibGUgJT4lCiAgbWVyZ2VfY29sdW1ucygibWV0aG9kcyIsIGNvbHVtbnNfbWV0aG9kcykgJT4lCiAgbWVyZ2VfY29sdW1ucygibGltaXRhdGlvbnMiLCBjb2x1bW5zX2xpbWl0YXRpb25zKSAlPiUKICBtZXJnZV9jb2x1bW5zKCJkaXNjaXBsaW5lcyIsIGNvbHVtbnNfZGlzY2lwbGluZXMpICU+JQogIG1lcmdlX2NvbHVtbnMoIm9iamVjdGl2ZXMiLCBjb2x1bW5zX29iamVjdGl2ZXMpICU+JQogIG1lcmdlX2NvbHVtbnMoImxvY2F0aW9uIiwgY29sdW1uc19sb2NhdGlvbikgJT4lCiAgbWVyZ2VfY29sdW1ucygicmVzdWx0cyIsIGNvbHVtbnNfcmVzdWx0cykgJT4lCiAgbWVyZ2VfY29sdW1ucygiY29sbGVjdGVkIiwgY29sdW1uc19jb2xsZWN0ZWQpICU+JQogIG1lcmdlX2NvbHVtbnMoInNvdXJjZSIsIGNvbHVtbnNfc291cmNlKSAlPiUKICBtZXJnZV9jb2x1bW5zKCJlZHVjYXRpb250eXBlIiwgY29sdW1uc19lZHVjYXRpb250eXBlKQoKIyBEaXNwbGF5IG9ubHkgdGhlICd5ZWFyJyBjb2x1bW4gYWxvbmcgd2l0aCBhbGwgbmV3bHkgY3JlYXRlZCBjb2x1bW5zCnByaW50KGRhdGFjbGVhbmluZ3RhYmxlICU+JSBzZWxlY3QobWV0aG9kcywgbGltaXRhdGlvbnMsIGRpc2NpcGxpbmVzLCBvYmplY3RpdmVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiwgcmVzdWx0cywgY29sbGVjdGVkLCBzb3VyY2UsIGVkdWNhdGlvbnR5cGUpLCB3aWR0aCA9IEluZikKCmBgYAoKYGBge3IgbWVyZ2UgZXhpc3RpbmcgY29sdW1uc30KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJ5CmxpYnJhcnkoZHBseXIpCgojIEZ1bmN0aW9uIHRvIG1lcmdlIHNlbGVjdGVkIGNvbHVtbnMgaW50byBhbiBleGlzdGluZyBjb2x1bW4gd2hpbGUga2VlcGluZyBjb2x1bW4gbmFtZXMKbWVyZ2VfaW50b19leGlzdGluZ19jb2x1bW4gPC0gZnVuY3Rpb24oZGYsIGV4aXN0aW5nX2NvbHVtbiwgbmV3X2NvbHVtbnMpIHsKICBleGlzdGluZ19jb2xzIDwtIGludGVyc2VjdChuZXdfY29sdW1ucywgY29sbmFtZXMoZGYpKSAgIyBLZWVwIG9ubHkgZXhpc3RpbmcgY29sdW1ucwoKICBpZiAobGVuZ3RoKGV4aXN0aW5nX2NvbHMpID4gMCkgeyAgIyBPbmx5IHByb2NlZWQgaWYgY29sdW1ucyBleGlzdAogICAgZGYgPC0gZGYgJT4lCiAgICAgIG11dGF0ZSghIWV4aXN0aW5nX2NvbHVtbiA6PSBhcHBseSguW2MoZXhpc3RpbmdfY29sdW1uLCBleGlzdGluZ19jb2xzKV0sIDEsIGZ1bmN0aW9uKHgpIHsKICAgICAgICBwYXN0ZShuYW1lcyh4KVshaXMubmEoeCkgJiB4ICE9ICIiXSwgeFshaXMubmEoeCkgJiB4ICE9ICIiXSwgc2VwID0gIjogIiwgY29sbGFwc2UgPSAiOyAiKQogICAgICB9KSkgJT4lCiAgICAgIHNlbGVjdCgtYWxsX29mKGV4aXN0aW5nX2NvbHMpKSAgIyBSZW1vdmUgbWVyZ2VkIGNvbHVtbnMKICB9CiAgCiAgcmV0dXJuKGRmKQp9CgojIEFwcGx5IG1lcmdpbmcgZnVuY3Rpb24gdG8gbW92ZSBjb2x1bW5zIHVuZGVyIGV4aXN0aW5nIG9uZXMKZGF0YWNsZWFuaW5ndGFibGUgPC0gZGF0YWNsZWFuaW5ndGFibGUgJT4lCiAgbWVyZ2VfaW50b19leGlzdGluZ19jb2x1bW4oImVycm9yIiwgYygicXVlc3Rpb24iKSkgJT4lCiAgbWVyZ2VfaW50b19leGlzdGluZ19jb2x1bW4oImFydGZvcm0iLCBjKCJhcnRfbWFraW5nIiwgImlsbHVzdHJhdGlvbl9vZl9lc3NlbmNlIiwgInNraWxsX3RyYW5zZmVyIikpICU+JQogIG1lcmdlX2ludG9fZXhpc3RpbmdfY29sdW1uKCJ0aGVvcnkiLCBjKCJlZHVjYXRpb25hbF90aGVvcnkiLCAic2NpZW50aWZpY19leHBsYW5hdGlvbiIsICJlZHVjYXRpb25hbF90aGUiKSkKCiMgRGlzcGxheSB1cGRhdGVkIGRhdGFzZXQKcHJpbnQoZGF0YWNsZWFuaW5ndGFibGUgJT4lIHNlbGVjdChlcnJvciwgYXJ0Zm9ybSwgdGhlb3J5KSwgd2lkdGggPSBJbmYpCmBgYAoKYGBge3IgcmVuYW1lIGNvbHVtbnN9CgojIERlZmluZSB0aGUgZGVzaXJlZCBjb2x1bW4gb3JkZXIgKGFzc3VtaW5nIHRoZSBkYXRhZnJhbWUgYWxyZWFkeSBoYXMgJ2F1dGhvcicgYXMgZGVzaXJlZCkKZGVzaXJlZF9vcmRlciA8LSBjKCJ0aXRsZSIsICJhdXRob3IiLCAiY29sbGVjdGVkIiwgIk5vVGFnIiwgInNvdXJjZSIsIAogICAgICAgICAgICAgICAgICAgIm9iamVjdGl2ZXMiLCAibWV0aG9kcyIsICJkYXRhX2NvbGxlY3Rpb24iLCAibnVtYmVyIiwgInBhcnRpY2lwYW50cyIsIAogICAgICAgICAgICAgICAgICAgImRhdGFfYW5hbHlzaXMiLCAiY2FzZSIsICJkaXNjaXBsaW5lcyIsICJsb2NhdGlvbiIsICJlZHVjYXRpb250eXBlIiwgCiAgICAgICAgICAgICAgICAgICAiYnVzaW5lc3NfY29udGV4dCIsICJhcnRmb3JtIiwgInJlYXNvbl9hcnQiLCAibGVhcm5pbmdfb3V0Y29tZSIsIAogICAgICAgICAgICAgICAgICAgIm91dGNvbWVfb3JnYW5pc2F0aW9uIiwgInRoZW9yeSIsICJpbnRlcmVzdGluZ19wZXJzcGVjdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgImNvbnNpZGVyYXRpb25fcmVzZWFyY2giLCAiY29uc2lkZXJhdGlvbl90ZWFjaGluZyIsICJjb25zaWRlcmF0aW9uX2J1c2luZXNzIiwgCiAgICAgICAgICAgICAgICAgICAicmVjb21tZW5kYXRpb25fdGVhY2hpbmciLCAicmVjb21tZW5kYXRpb25fYnVzaW5lc3MiLCAKICAgICAgICAgICAgICAgICAgICJyZWNvbW1lbmRhdGlvbl9yZXNlYXJjaCIsICJsaW1pdGF0aW9ucyIsICJmdXR1cmVfcmVzZWFyY2giKQoKIyBSZW9yZGVyIGNvbHVtbnMgd2l0aCB0aGUgdW5tZW50aW9uZWQgb25lcyBhcHBlbmRlZCBhdCB0aGUgZW5kLgpkYXRhY2xlYW5pbmd0YWJsZTIwMjUwMzI2IDwtIGRhdGFjbGVhbmluZ3RhYmxlICU+JQogIHNlbGVjdChhbGxfb2YoaW50ZXJzZWN0KGRlc2lyZWRfb3JkZXIsIGNvbG5hbWVzKC4pKSksCiAgICAgICAgIGV2ZXJ5dGhpbmcoKSkKCiMgUmVtb3ZlIGR1cGxpY2F0ZSBjb2x1bW5zIGluIGNhc2UgYW55IGFwcGVhciB0d2ljZS4KZGF0YWNsZWFuaW5ndGFibGUyMDI1MDMyNiA8LSBkYXRhY2xlYW5pbmd0YWJsZTIwMjUwMzI2WywgIWR1cGxpY2F0ZWQobmFtZXMoZGF0YWNsZWFuaW5ndGFibGUyMDI1MDMyNikpXQoKIyBEaXNwbGF5IHRoZSB1cGRhdGVkIGRhdGFmcmFtZQpwcmludChkYXRhY2xlYW5pbmd0YWJsZTIwMjUwMzI2LCB3aWR0aCA9IEluZikKCmBgYAoKYGBge3J9CiMgTG9hZCB0aGUgbmVjZXNzYXJ5IHBhY2thZ2UKbGlicmFyeShvcGVueGxzeCkKCiMgRGVmaW5lIHRoZSBmaWxlIHBhdGgKZmlsZV9wYXRoIDwtICIvVXNlcnMvQWNjb3VudHRpamRlbGlqay9EZXNrdG9wL2RhdGFjbGVhbmluZ3RhYmxlMjAyNTAzMjYueGxzeCIKCiMgQ3JlYXRlIGEgbmV3IHdvcmtib29rIGFuZCBhZGQgYSB3b3Jrc2hlZXQKd2IgPC0gY3JlYXRlV29ya2Jvb2soKQphZGRXb3Jrc2hlZXQod2IsICJTaGVldDEiKQoKIyBXcml0ZSB0aGUgZGF0YSB0byB0aGUgd29ya3NoZWV0CndyaXRlRGF0YSh3Yiwgc2hlZXQgPSAiU2hlZXQxIiwgZGF0YWNsZWFuaW5ndGFibGUyMDI1MDMyNikKCiMgRGVmaW5lIHN0eWxlIGZvciBOQSBvciBlbXB0eSBjZWxscwpuYV9zdHlsZSA8LSBjcmVhdGVTdHlsZShmZ0ZpbGwgPSAiI0ZGRDFEMSIpICAjIGxpZ2h0IHJlZCBiYWNrZ3JvdW5kCgojIExvb3AgdGhyb3VnaCBlYWNoIGNlbGwgYW5kIGFwcGx5IHN0eWxlIGlmIGl0J3MgTkEgb3IgZW1wdHkgc3RyaW5nCmZvciAoaSBpbiAxOm5yb3coZGF0YWNsZWFuaW5ndGFibGUyMDI1MDMyNikpIHsKICBmb3IgKGogaW4gMTpuY29sKGRhdGFjbGVhbmluZ3RhYmxlMjAyNTAzMjYpKSB7CiAgICB2YWx1ZSA8LSBkYXRhY2xlYW5pbmd0YWJsZTIwMjUwMzI2W2ksIGpdCiAgICBpZiAoaXMubmEodmFsdWUpIHx8IHRyaW13cyhhcy5jaGFyYWN0ZXIodmFsdWUpKSA9PSAiIikgewogICAgICBhZGRTdHlsZSh3Yiwgc2hlZXQgPSAiU2hlZXQxIiwgc3R5bGUgPSBuYV9zdHlsZSwgcm93cyA9IGkgKyAxLCBjb2xzID0gaiwgZ3JpZEV4cGFuZCA9IFRSVUUpCiAgICB9CiAgfQp9CgojIFNhdmUgdGhlIHdvcmtib29rCnNhdmVXb3JrYm9vayh3YiwgZmlsZSA9IGZpbGVfcGF0aCwgb3ZlcndyaXRlID0gVFJVRSkKCiMgQ29uZmlybSB0aGUgZmlsZSB3YXMgc2F2ZWQKY2F0KCJGaWxlIHNhdmVkIHRvOiIsIGZpbGVfcGF0aCkKCgpgYGAKCgoK